import React, { useEffect, useRef, useState, useCallback } from 'react'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { useNavigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { message } from 'antd'
import { useSelector } from 'react-redux'
import type { RootState } from '../../store'
import { isAdmin } from '../../utils/rbac'
import './index.css'

// TypeScript 类型定义
interface ProductInfo {
  id: number
  name: string
  price: string
  description: string
  buyInfo: string
  color: string
}

interface CircleData {
  mesh: THREE.Mesh
  originalColor: THREE.Color
  productInfo: ProductInfo
}

interface InfoPanelProps {
  productInfo: ProductInfo | null
  position: { x: number; y: number }
  onClose: () => void
}

// 信息面板组件
const InfoPanel: React.FC<InfoPanelProps> = ({ productInfo, position, onClose }) => {
  if (!productInfo) return null

  return (
    <div
      className="info-panel"
      style={{
        position: 'absolute',
        left: position.x,
        top: position.y,
        background: 'rgba(0, 0, 0, 0.9)',
        color: 'white',
        padding: '20px',
        borderRadius: '12px',
        border: '2px solid rgba(255, 255, 255, 0.2)',
        backdropFilter: 'blur(10px)',
        maxWidth: '300px',
        zIndex: 1000,
        boxShadow: '0 8px 32px rgba(0, 0, 0, 0.3)',
        animation: 'fadeInScale 0.3s ease-out'
      }}
    >
      <button
        onClick={onClose}
        style={{
          position: 'absolute',
          right: '10px',
          top: '10px',
          background: 'transparent',
          border: 'none',
          color: 'white',
          fontSize: '18px',
          cursor: 'pointer',
          padding: '5px'
        }}
      >
        ×
      </button>
      <h3 style={{ margin: '0 0 10px 0', color: productInfo.color }}>{productInfo.name}</h3>
      <p style={{ margin: '5px 0', fontSize: '18px', fontWeight: 'bold' }}>价格: {productInfo.price}</p>
      <p style={{ margin: '10px 0', lineHeight: '1.4' }}>{productInfo.description}</p>
      <p style={{ margin: '10px 0', fontSize: '14px', color: '#ccc' }}>{productInfo.buyInfo}</p>
      <button
        style={{
          background: productInfo.color,
          color: 'white',
          border: 'none',
          padding: '10px 20px',
          borderRadius: '6px',
          cursor: 'pointer',
          fontSize: '14px',
          marginTop: '10px'
        }}
      >
        立即购买
      </button>
    </div>
  )
}

const Exhibition: React.FC = () => {
  const containerRef = useRef<HTMLDivElement>(null)
  const navigate = useNavigate()
  const { t } = useTranslation()
  const { userInfo } = useSelector((state: RootState) => state.user)

  useEffect(() => {
    if (!isAdmin(userInfo)) {
      message.warning('权限不足：仅管理员可访问展览页')
      navigate('/Layout', { replace: true })
    }
  }, [userInfo])

  // 新增状态管理
  const [selectedProduct, setSelectedProduct] = useState<ProductInfo | null>(null)
  const [panelPosition, setPanelPosition] = useState({ x: 0, y: 0 })
  const circlesRef = useRef<CircleData[]>([])
  const raycasterRef = useRef<THREE.Raycaster>(new THREE.Raycaster())
  const mouseRef = useRef<THREE.Vector2>(new THREE.Vector2())
  const sceneRef = useRef<THREE.Scene | null>(null)
  const cameraRef = useRef<THREE.Camera | null>(null)
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null)

  // 移动状态与按钮样式
  const moveRef = useRef({ forward: false, backward: false, left: false, right: false })
  const press = (k: keyof typeof moveRef.current) => { moveRef.current[k] = true }
  const release = (k: keyof typeof moveRef.current) => { moveRef.current[k] = false }

  // 商品模拟数据
  const productData: ProductInfo[] = [
    {
      id: 1,
      name: "智能台灯",
      price: "¥299",
      description: "现代简约设计，支持无线充电和智能调光，完美融入卧室环境。",
      buyInfo: "包邮 | 7天无理由退换 | 1年质保",
      color: "#ff4444"
    },
    {
      id: 2,
      name: "舒适床垫",
      price: "¥1,299",
      description: "记忆棉材质，符合人体工学设计，提供优质睡眠体验。",
      buyInfo: "免费送货上门 | 100天试睡 | 10年质保",
      color: "#44ff44"
    },
    {
      id: 3,
      name: "实木衣柜",
      price: "¥2,599",
      description: "精选橡木材质，大容量储物空间，经典耐用设计。",
      buyInfo: "专业安装 | 环保认证 | 5年质保",
      color: "#4444ff"
    },
    {
      id: 4,
      name: "装饰画框",
      price: "¥199",
      description: "现代艺术风格装饰画，为房间增添艺术气息。",
      buyInfo: "精美包装 | 30天退换 | 防潮防褪色",
      color: "#ffff44"
    },
    {
      id: 5,
      name: "香薰机",
      price: "¥399",
      description: "超声波雾化技术，静音运行，营造舒适居住氛围。",
      buyInfo: "送精油套装 | 静音保证 | 2年质保",
      color: "#ff44ff"
    },
    {
      id: 6,
      name: "智能音响",
      price: "¥899",
      description: "360度环绕立体声，支持语音控制和蓝牙连接，音质清晰饱满。",
      buyInfo: "免费配送 | 智能家居兼容 | 3年质保",
      color: "#44ffff"
    },
    {
      id: 7,
      name: "护眼落地灯",
      price: "¥599",
      description: "无频闪护眼技术，三档调光模式，现代北欧风格设计。",
      buyInfo: "专业护眼认证 | 节能环保 | 2年质保",
      color: "#ff8844"
    }
  ]

  // 创建圆形几何体函数
  const createInteractiveCircles = useCallback((scene: THREE.Scene, modelBounds: THREE.Box3) => {
    const circles: CircleData[] = []
    const radius = 1 // 圆形半径 1 米

    // 计算模型的中心和尺寸
    const center = modelBounds.getCenter(new THREE.Vector3())
    const size = modelBounds.getSize(new THREE.Vector3())

    // 定义七个圆形的相对位置（基于模型边界）
    const positions = [
      new THREE.Vector3(center.x - size.x * 0.3, center.y + 1, center.z - size.z * 0.3), // 左前
      new THREE.Vector3(center.x + size.x * 0.3, center.y + 1, center.z - size.z * 0.3), // 右前
      new THREE.Vector3(center.x, center.y + 1, center.z), // 中心
      new THREE.Vector3(center.x - size.x * 0.2, center.y + 1, center.z + size.z * 0.3), // 左后
      new THREE.Vector3(center.x + size.x * 0.2, center.y + 1, center.z + size.z * 0.3), // 右后
      new THREE.Vector3(center.x - size.x * 0.4, center.y + 1, center.z), // 左侧
      new THREE.Vector3(center.x + size.x * 0.4, center.y + 1, center.z)  // 右侧
    ]

    positions.forEach((position, index) => {
      // 创建圆形几何体
      const geometry = new THREE.CircleGeometry(radius, 32)
      const material = new THREE.MeshLambertMaterial({
        color: productData[index].color,
        transparent: true,
        opacity: 0.8,
        side: THREE.DoubleSide
      })

      const circle = new THREE.Mesh(geometry, material)
      circle.position.copy(position)
      circle.lookAt(new THREE.Vector3(position.x, position.y + 1, position.z)) // 面向上方
      circle.userData = { productId: productData[index].id, isInteractive: true }

      // 添加发光效果
      const glowGeometry = new THREE.CircleGeometry(radius * 1.2, 32)
      const glowMaterial = new THREE.MeshBasicMaterial({
        color: productData[index].color,
        transparent: true,
        opacity: 0.3,
        side: THREE.DoubleSide
      })
      const glow = new THREE.Mesh(glowGeometry, glowMaterial)
      glow.position.copy(position)
      glow.lookAt(new THREE.Vector3(position.x, position.y + 1, position.z))

      scene.add(circle)
      scene.add(glow)

      circles.push({
        mesh: circle,
        originalColor: new THREE.Color(productData[index].color),
        productInfo: productData[index]
      })
    })

    return circles
  }, [])

  // 防抖函数
  const debounce = useCallback((func: Function, wait: number) => {
    let timeout: any;
    return function executedFunction(...args: any[]) {
      const later = () => {
        clearTimeout(timeout)
        func(...args)
      }
      clearTimeout(timeout)
      timeout = setTimeout(later, wait)
    }
  }, [])

  // 点击动画效果
  const animateCircleClick = useCallback((mesh: THREE.Mesh) => {
    const originalScale = mesh.scale.clone()
    const originalColor = (mesh.material as THREE.MeshLambertMaterial).color.clone()
    const highlightColor = new THREE.Color(0xffffff)

    // 缩放和颜色变化动画
    const animateScale = (progress: number) => {
      const scale = 1 + Math.sin(progress * Math.PI) * 0.3
      mesh.scale.setScalar(scale)

      // 颜色插值
      const material = mesh.material as THREE.MeshLambertMaterial
      material.color.lerpColors(originalColor, highlightColor, Math.sin(progress * Math.PI) * 0.5)

      if (progress < 1) {
        requestAnimationFrame(() => animateScale(progress + 0.05))
      } else {
        // 恢复原始状态
        mesh.scale.copy(originalScale)
        material.color.copy(originalColor)
      }
    }

    animateScale(0)
  }, [])

  // 点击事件处理函数
  const handleCircleClick = useCallback((event: MouseEvent) => {
    if (!sceneRef.current || !cameraRef.current || !rendererRef.current) return

    const rect = rendererRef.current.domElement.getBoundingClientRect()
    mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
    mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1

    raycasterRef.current.setFromCamera(mouseRef.current, cameraRef.current)
    const intersects = raycasterRef.current.intersectObjects(
      circlesRef.current.map(circle => circle.mesh)
    )

    if (intersects.length > 0) {
      const clickedObject = intersects[0].object
      const circleData = circlesRef.current.find(circle => circle.mesh === clickedObject)

      if (circleData) {
        // 触发点击动画
        animateCircleClick(circleData.mesh)

        // 显示信息面板
        setSelectedProduct(circleData.productInfo)
        setPanelPosition({
          x: Math.min(event.clientX, window.innerWidth - 320),
          y: Math.min(event.clientY, window.innerHeight - 200)
        })
      }
    } else {
      // 点击空白处关闭面板
      setSelectedProduct(null)
    }
  }, [animateCircleClick])

  // 防抖的点击处理函数
  const debouncedHandleClick = useCallback(
    debounce(handleCircleClick, 200),
    [handleCircleClick, debounce]
  )

  const btnStyle: React.CSSProperties = {
    width: 40,
    height: 40,
    borderRadius: 8,
    border: '1px solid rgba(255,255,255,0.35)',
    background: 'rgba(0,0,0,0.45)',
    color: '#fff',
    fontSize: 18,
    lineHeight: '40px',
    textAlign: 'center',
    cursor: 'pointer',
    userSelect: 'none'
  }

  useEffect(() => {
    const container = containerRef.current
    if (!container) return
    const width = container.clientWidth || window.innerWidth
    const height = container.clientHeight || window.innerHeight
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
    renderer.setSize(width, height)
    renderer.shadowMap.enabled = true
    renderer.setClearColor(0x000000, 0) // 透明背景
    container.appendChild(renderer.domElement)
    const scene = new THREE.Scene()
    scene.background = null // 移除背景，仅显示模型
    const camera = new THREE.PerspectiveCamera(80, width / height, 0.01, 20000)
    camera.position.set(5, 8, 15)

    // 保存引用供点击事件使用
    sceneRef.current = scene
    cameraRef.current = camera
    rendererRef.current = renderer
    const controls = new OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
    controls.minDistance = 0.1
    const ambient = new THREE.AmbientLight(0xffffff, 0.6)
    scene.add(ambient)
    const dirLight = new THREE.DirectionalLight(0xffffff, 0.8)
    dirLight.position.set(10, 20, 10)
    dirLight.castShadow = true
    scene.add(dirLight)
    const loader = new GLTFLoader()
    const modelUrl = new URL('../../assets/3DGLB/bedroom.glb', import.meta.url).href
    let animationId = 0
    const clock = new THREE.Clock()
    const SPEED = 4 // 行走速度（单位/秒）
    loader.load(
      modelUrl,
      (gltf) => {
        const root = gltf.scene
        root.traverse((obj: any) => {
          if ((obj as any).isMesh) {
            obj.castShadow = true
            obj.receiveShadow = true
          }
        })
        scene.add(root)

        // 创建交互圆形
        const box = new THREE.Box3().setFromObject(root)
        circlesRef.current = createInteractiveCircles(scene, box)

        // 自适应相机到模型内部并旋转
        const center = box.getCenter(new THREE.Vector3())
        const size = box.getSize(new THREE.Vector3())
        camera.position.copy(center)
        const baseDir = new THREE.Vector3(0, 0, -1)
        const yaw = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)
        const pitch = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI / 2)
        const dir = baseDir.clone().applyQuaternion(yaw).applyQuaternion(pitch)
        const epsilon = Math.max(0.05, size.length() * 0.001)
        controls.target.copy(center.clone().add(dir.multiplyScalar(epsilon)))
        controls.update()
      },
      undefined,
      (err) => {
        console.error('GLTF 加载失败:', err)
      }
    )
    // 键盘控制（WASD/方向键）
    const onKeyDown = (e: KeyboardEvent) => {
      switch (e.key) {
        case 'w': case 'W': case 'ArrowUp': moveRef.current.forward = true; break
        case 's': case 'S': case 'ArrowDown': moveRef.current.backward = true; break
        case 'a': case 'A': case 'ArrowLeft': moveRef.current.left = true; break
        case 'd': case 'D': case 'ArrowRight': moveRef.current.right = true; break
      }
    }
    const onKeyUp = (e: KeyboardEvent) => {
      switch (e.key) {
        case 'w': case 'W': case 'ArrowUp': moveRef.current.forward = false; break
        case 's': case 'S': case 'ArrowDown': moveRef.current.backward = false; break
        case 'a': case 'A': case 'ArrowLeft': moveRef.current.left = false; break
        case 'd': case 'D': case 'ArrowRight': moveRef.current.right = false; break
      }
    }
    window.addEventListener('keydown', onKeyDown)
    window.addEventListener('keyup', onKeyUp)

    // 添加点击事件监听
    renderer.domElement.addEventListener('click', debouncedHandleClick as any)

    const onResize = () => {
      const w = container.clientWidth || window.innerWidth
      const h = container.clientHeight || window.innerHeight
      renderer.setSize(w, h)
      camera.aspect = w / h
      camera.updateProjectionMatrix()
    }
    window.addEventListener('resize', onResize)
    const animate = () => {
      // 第一人称移动：基于相机前向与右向
      const dt = clock.getDelta()
      const forward = new THREE.Vector3()
      camera.getWorldDirection(forward)
      forward.normalize()
      const right = forward.clone().cross(camera.up).normalize()
      const move = new THREE.Vector3()
      if (moveRef.current.forward) move.add(forward)
      if (moveRef.current.backward) move.addScaledVector(forward, -1)
      if (moveRef.current.left) move.addScaledVector(right, -1)
      if (moveRef.current.right) move.add(right)
      if (move.lengthSq() > 0) {
        move.normalize().multiplyScalar(SPEED * dt)
        camera.position.add(move)
        controls.target.add(move)
      }
      controls.update()
      renderer.render(scene, camera)
      animationId = requestAnimationFrame(animate)
    }
    animate()
    return () => {
      cancelAnimationFrame(animationId)
      window.removeEventListener('resize', onResize)
      window.removeEventListener('keydown', onKeyDown)
      window.removeEventListener('keyup', onKeyUp)
      renderer.domElement.removeEventListener('click', debouncedHandleClick as any)
      controls.dispose()
      renderer.dispose()
      if (renderer.domElement && renderer.domElement.parentNode) {
        renderer.domElement.parentNode.removeChild(renderer.domElement)
      }
    }
  }, [])
  // 按钮活动状态
  const [activeButtons, setActiveButtons] = useState({
    forward: false,
    backward: false,
    left: false,
    right: false
  });

  // 检测是否为移动设备
  const isMobile = () => {
    return window.innerWidth <= 768 || ('ontouchstart' in window);
  }

  // 添加触摸反馈效果
  const handleTouchFeedback = (e: React.TouchEvent) => {
    // 添加触摸反馈效果
    const button = e.currentTarget as HTMLButtonElement;
    button.style.transform = 'scale(0.95)';
    setTimeout(() => {
      button.style.transform = '';
    }, 200);
  }

  // 修改按下和释放函数，同时更新活动状态
  const pressWithAnimation = (k: keyof typeof moveRef.current) => {
    moveRef.current[k] = true;
    setActiveButtons(prev => ({ ...prev, [k]: true }));
  }

  const releaseWithAnimation = (k: keyof typeof moveRef.current) => {
    moveRef.current[k] = false;
    setActiveButtons(prev => ({ ...prev, [k]: false }));
  }

  return (
    <div style={{ position: 'relative', width: '100vw', height: '100vh', overflow: 'hidden' }}>
      {/* 左上角返回首页 */}
      <button
        className="btn-3d back-btn"
        style={{ position: 'absolute', left: 16, top: 16, zIndex: 11 }}
        onClick={() => navigate('/Layout')}
      >
        <span>←</span> {t('back_home')}
      </button>

      {/* 信息面板 */}
      {selectedProduct && (
        <InfoPanel
          productInfo={selectedProduct}
          position={panelPosition}
          onClose={() => setSelectedProduct(null)}
        />
      )}

      <div ref={containerRef} style={{ width: '100%', height: '100%' }} />
      {/* 左下角方向按钮（第一人称移动） */}
      <div style={{ position: 'absolute', left: 16, bottom: 16, display: 'grid', gridTemplateColumns: '45px 45px 45px', gridTemplateRows: '45px 45px 45px', gap: 10, zIndex: 10 }}>
        <button
          className={`btn-3d direction-btn ${activeButtons.forward ? 'active' : ''}`}
          style={{ gridColumn: 2, gridRow: 1 }}
          onMouseDown={() => pressWithAnimation('forward')}
          onMouseUp={() => releaseWithAnimation('forward')}
          onMouseLeave={() => releaseWithAnimation('forward')}
          onTouchStart={(e) => { pressWithAnimation('forward'); handleTouchFeedback(e); }}
          onTouchEnd={() => releaseWithAnimation('forward')}
        >↑</button>
        <button
          className={`btn-3d direction-btn ${activeButtons.left ? 'active' : ''}`}
          style={{ gridColumn: 1, gridRow: 2 }}
          onMouseDown={() => pressWithAnimation('left')}
          onMouseUp={() => releaseWithAnimation('left')}
          onMouseLeave={() => releaseWithAnimation('left')}
          onTouchStart={(e) => { pressWithAnimation('left'); handleTouchFeedback(e); }}
          onTouchEnd={() => releaseWithAnimation('left')}
        >←</button>
        <button
          className={`btn-3d direction-btn ${activeButtons.right ? 'active' : ''}`}
          style={{ gridColumn: 3, gridRow: 2 }}
          onMouseDown={() => pressWithAnimation('right')}
          onMouseUp={() => releaseWithAnimation('right')}
          onMouseLeave={() => releaseWithAnimation('right')}
          onTouchStart={(e) => { pressWithAnimation('right'); handleTouchFeedback(e); }}
          onTouchEnd={() => releaseWithAnimation('right')}
        >→</button>
        <button
          className={`btn-3d direction-btn ${activeButtons.backward ? 'active' : ''}`}
          style={{ gridColumn: 2, gridRow: 3 }}
          onMouseDown={() => pressWithAnimation('backward')}
          onMouseUp={() => releaseWithAnimation('backward')}
          onMouseLeave={() => releaseWithAnimation('backward')}
          onTouchStart={(e) => { pressWithAnimation('backward'); handleTouchFeedback(e); }}
          onTouchEnd={() => releaseWithAnimation('backward')}
        >↓</button>
      </div>
    </div>
  )
}

export default Exhibition
